package com.jobcn.timer;

import com.jobcn.config.SpiderConfig;
import com.jobcn.dic.SpiderDic;
import com.jobcn.entity.SpiderSetting;
import com.jobcn.entity.SpiderTask;
import com.jobcn.repository.spider.SpiderInfoRepository;
import com.jobcn.repository.spider.SpiderMerRepository;
import com.jobcn.repository.spider.SpiderSettingRepository;
import com.jobcn.repository.spider.SpiderTaskRepository;
import com.jobcn.service.BizoppService;
import com.jobcn.service.SpiderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static com.jobcn.dic.SpiderDic.STATUS_PROCESSING;

/**
 * 58爬虫的定时任务
 * Created by winson on 2016/12/5.
 */
@Component
@EnableScheduling
public class Spider58Timer {
    final Logger logger = LoggerFactory.getLogger(Spider58Timer.class);
    @Autowired
    private SpiderSettingRepository spiderSettingRepository;
    @Autowired
    private SpiderTaskRepository spiderTaskRepository;
    @Autowired
    private SpiderInfoRepository spiderInfoRepository;
    @Autowired
    private SpiderMerRepository spiderMerRepository;
    @Autowired
    private SpiderService spiderService;
    @Autowired
    private BizoppService bizoppService;
    @Autowired
    private SpiderConfig spiderConfig;
    private static SpiderTask spiderTask;
    private static long merTotal;
    private static long infoTotal;

    /**
     * 每周插入一条58爬虫任务
     */
    @Scheduled(cron = "0 0 0 ? * SAT")
    public void insetTaskEveryWeek() {
        SpiderSetting spiderSetting = spiderSettingRepository.findOne(SpiderDic.SPIDER_SOURCE_58);
        if (!spiderSetting.getSpiderStatus()) {
            return;
        }
        SpiderTask task = new SpiderTask();
        task.setStatus(SpiderDic.STATUS_WAIT);
        task.setSource(SpiderDic.SPIDER_SOURCE_58);
        task.setMsg("等待执行");
        task.setTriggerType(SpiderDic.TRIGGER_TIMMER);
        task.setUpdateDatetime(new Date());
        task.setTaskType(SpiderDic.TASK_SPIDER);
        spiderTaskRepository.save(task);
    }

    /**
     * 1.定时查找是否有等待执行的任务,且没有执行中的任务
     * 2.定时查找是否有被终止操作的任务
     */
    @Scheduled(initialDelay = 10000, fixedDelay = 10000)
    public void autoSpiderRun() {
        List<SpiderTask> spiderTaskList = spiderTaskRepository.findAllByStatusAndTaskType(SpiderDic.STATUS_PROCESSING, SpiderDic.TASK_SPIDER);
        //定时检查任务是否被终止
        if (spiderTaskList == null || spiderTaskList.size() == 0) {
            spiderService.spider58Close();
        }
        //如果已经有正在执行中的任务了，则不执行咯
        if (spiderTaskList != null & spiderTaskList.size() > 0) {
            //logger.info("已经有执行中的任务,不启动新爬虫任务");
            return;
        }
        SpiderTask spiderTask = spiderTaskRepository.findTopByStatusAndTaskType(SpiderDic.STATUS_WAIT, SpiderDic.TASK_SPIDER);
        if (spiderTask == null) {
            //logger.info("找不到可执行的新爬虫任务");
            return;
        }
        logger.info("触发爬虫任务：{}", spiderTask.getId());
        spiderService.spider58Run(spiderConfig.getIpPool(), spiderTask);
    }

    /**
     * 定时查找是否有等待执行的更新任务,且没有执行中的任务
     */
    @Scheduled(initialDelay = 10000, fixedDelay = 10000)
    public void autoUpdateRun() {
        List<SpiderTask> spiderTaskList = spiderTaskRepository.findAllByStatusAndTaskType(SpiderDic.STATUS_PROCESSING, SpiderDic.TASK_UPDATE);
        //如果已经有正在执行中的任务了，则不执行咯
        if (spiderTaskList != null & spiderTaskList.size() > 0) {
            return;
        }
        SpiderTask spiderTask = spiderTaskRepository.findTopByStatusAndTaskType(SpiderDic.STATUS_WAIT, SpiderDic.TASK_UPDATE);
        if (spiderTask == null) {
            return;
        }
        logger.info("触发更新任务：{}", spiderTask.getId());
        spiderTask.setStartDatetime(new Date());
        spiderTask.setStatus(STATUS_PROCESSING);
        spiderTask.setUpdateDatetime(new Date());
        spiderTask.setMsg("更新中");
        spiderTask = spiderTaskRepository.save(spiderTask);
        bizoppService.update58ToBizopp(spiderTask);
    }

    //检查执行中的任务是否挂掉了？如果超过1分钟没变，则认为是挂掉了
    @Scheduled(initialDelay = 10000, fixedDelay = 60000)
    public void checkSpider() {
        SpiderTask spiderTaskNew = spiderTaskRepository.findTopByStatusAndTaskType(SpiderDic.STATUS_PROCESSING, SpiderDic.TASK_SPIDER);
        SpiderTask updateTaskNew = spiderTaskRepository.findTopByStatusAndTaskType(SpiderDic.STATUS_PROCESSING, SpiderDic.TASK_UPDATE);
        //
        if (spiderTaskNew != null) {
            if (spiderTask != null) {
                if ((spiderTaskNew.getInfoCount().equals(spiderTask.getInfoCount()))
                        && (spiderTaskNew.getMerCount().equals(spiderTask.getMerCount()))) {
                    spiderTaskNew.setStatus(SpiderDic.STATUS_EXCEPTION);
                    spiderTaskNew.setMsg("爬虫超时未动");
                    spiderTaskRepository.save(spiderTaskNew);
                }
            }
            spiderTask = spiderTaskNew;
        }
        //如果超过3分钟没变，则认为是挂掉了
        if (updateTaskNew != null) {
            if ((updateTaskNew.getInfoCount().equals(infoTotal))
                    && (updateTaskNew.getMerCount().equals(merTotal))) {
                updateTaskNew.setStatus(SpiderDic.STATUS_EXCEPTION);
                updateTaskNew.setMsg("更新超时未动");
                spiderTaskRepository.save(updateTaskNew);
            }
            infoTotal = updateTaskNew.getInfoCount();
            merTotal = updateTaskNew.getMerCount();
        }

    }
    /**
     * 定时更新执行中的爬虫任务爬取的服务和商家数量
     */
    @Scheduled(initialDelay = 10000, fixedDelay = 10000)
    public void updateSpiderCount() {
        List<SpiderTask> spiderTaskList = spiderTaskRepository.findAllByStatusAndTaskType(SpiderDic.STATUS_PROCESSING, SpiderDic.TASK_SPIDER);
        for (SpiderTask task : spiderTaskList) {
            task.setInfoCount(spiderInfoRepository.countByTaskId(task.getId()));
            task.setMerCount(spiderMerRepository.countByTaskId(task.getId()));
            spiderTaskRepository.save(task);
        }
    }

}